再繼續往RxJS的道路之前,
先插播一則文章,回過頭來看Angular元件、服務、生命週期與執行的順序
透過ng cli
產出的元件,底下都會有以下兩個方法(Method)
constructor()
Typescript的構建物件函式ngOnInit()
Angular元件初始化時執行在初學階段,這兩者都可以視作元件初始化時做的事情
只要知道ngOnInit
執行的時機點晚於constructor
一些
因為constructor()
Typescript層的東西
其中小括號內()
是構建函式的Input參數(Parameter)
把這個物件所需要用到、所依賴的服務注入進來,提供給這整個物件使用(讓物件內的每個方法都可以取用到)
昨天看到的 HttpClient
是Angular內建的眾多服務(Service)之一,就是透過注入服務到元件中讓元件能使用該服務底下的方法。未來我們也會自行寫服務service.ts
,注入到自己寫的元件中。
所以執行順序為,
先執行構建物件,等構建完畢之後才執行Angular元件初始化
constructor() {
console.log('==== constructor ====')
}
ngOnInit(): void {
console.log('==== ngOnInit ====')
}
除了以上兩種預設的方法之外,還有很多內建方法
export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
constructor() {
console.log('==== constructor ====')
}
ngOnInit(): void {
console.log('==== ngOnInit ====')
}
ngAfterViewInit(): void {
console.log('==== ngAfterViewInit ====')
}
ngOnDestroy() {
console.log('==== ngOnDestroy ====')
}
}
這一行
implements OnInit, OnDestroy, AfterViewInit
實作介面
有加、沒加都不會對畫面產生影響因為
Javascript
沒有interface
,最終編譯都是相同結果
只是加了對程式碼風格較好,有助於IDE推斷介面型別
執行結果
constructor
構建一個物件首先執行的函式,在這裡引入物件所需用到的服務ngOnInit
生命週期 元件初始化,進入此元件做的事情,此時畫面尚未生成完畢ngAfterViewInit
生命週期 當畫面(View)渲染完畢才做的事
例如抓取頁面上的某個節點,若在畫面出現之前執行的話會抓不到元素而變成
undefined
ngOnDestroy
生命週期 離開、結束此元件時做的事情
刷新頁面或離開頁面都不會觸發效果
因為是這兩件事情主導權不在Angular手上,而是由瀏覽器銷毀
在未來提及Rouing
切換頁面元件時可以看到效果
以人類的生命週期來對應的話,分別是
constructor
建構胚胎卵,注入所需要的養分服務,以幫助未來成長ngOnInit
元件在媽媽的肚子裡面長好了ngAfterViewInit
畫面生出來了,我們肉眼看的見四肢了destroy
生命離開肉體軀殼,被大自然回收了我們在 app
與 store
兩個元件中,都分別印出以上四種狀態
修改 store.component.ts
...
export class StoreComponent implements OnInit, AfterViewInit, OnDestroy {
constructor() {
console.log('==== StoreComponent constructor ====')
}
ngOnInit(): void {
console.log('==== StoreComponent ngOnInit ====')
}
ngAfterViewInit(): void {
console.log('==== StoreComponent ngAfterViewInit ====')
}
ngOnDestroy(): void {
console.log('==== StoreComponent ngOnDestroy ====')
}
}
修改 app.component.ts
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
title = 'project03';
constructor() {
console.log('==== AppComponent constructor ====')
}
ngOnInit(): void {
console.log('==== AppComponent ngOnInit ====')
}
ngAfterViewInit(): void {
console.log('==== AppComponent ngAfterViewInit ====')
}
ngOnDestroy(): void {
console.log('==== AppComponent ngOnDestroy ====')
}
}
修改 app.component.html
<app-store></app-store>
結果畫面
可以看到巢狀的執行順序
先是App的建構,建構完畢跑進Store開始建構,接著開始Angular的生命週期,
從APP開始初始化,等Store初始化好了、畫面都好了,最終APP的畫面才好。
透過ng cli
建立一個名為svc
的服務
> ng g s svc
修改svc.service.ts
import { Injectable, OnInit } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class SvcService implements OnInit{
constructor() {
console.log('SvcService constructor')
}
}
接著分別在app.component.ts
與store.component.ts
中
加上這一段試試看效果
constructor(svc: SvcService) {
}
僅將svc: SvcService
加在 app.component.ts
的結果
僅將svc: SvcService
加在 store.component.ts
的結果
由此可見,注入的服務是在Construct()
的前一刻先被執行
服務(Service)沒有Angular生命週期
就算加了ngOnInit
等方法,也不會有任何作用
Angular生命週期只有元件(Component)、指示(Directive)有
import { Injectable, OnInit } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class SvcService implements OnInit{
constructor() {
console.log('SvcService constructor')
}
ngOnInit() {
console.log('SvcService ngOnInit')
}
}